IRQ: manually EOI migrating line interrupts
authorAndrew Cooper <andrew.cooper3@citrix.com>
Wed, 31 Aug 2011 14:19:24 +0000 (15:19 +0100)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Wed, 31 Aug 2011 14:19:24 +0000 (15:19 +0100)
commit12b6ea528fd6048bebcaee852d1b6be811907be3
treed49822a6409db3602a8b945abc2f0ae9e1bc424d
parenta81d0ee933c35323f32269dad37977934b6cbb28
IRQ: manually EOI migrating line interrupts

When migrating IO-APIC line level interrupts between PCPUs, the
migration code rewrites the IO-APIC entry to point to the new
CPU/Vector before EOI'ing it.

The EOI process says that EOI'ing the Local APIC will cause a
broadcast with the vector number, which the IO-APIC must listen to to
clear the IRR and Status bits.

In the case of migrating, the IO-APIC has already been
reprogrammed so the EOI broadcast with the old vector fails to match
the new vector, leaving the IO-APIC with an outstanding vector,
preventing any more use of that line interrupt.  This causes a lockup
especially when your root device is using PCI INTA (megaraid_sas
driver *ehem*)

However, the problem is mostly hidden because send_cleanup_vector()
causes a cleanup of all moving vectors on the current PCPU in such a
way which does not cause the problem, and if the problem has occured,
the writes it makes to the IO-APIC clears the IRR and Status bits
which unlocks the problem.

This fix is distinctly a temporary hack, waiting on a cleanup of the
irq code.  It checks for the edge case where we have moved the irq,
and manually EOI's the old vector with the IO-APIC which correctly
clears the IRR and Status bits.  Also, it protects the code which
updates irq_cfg by disabling interrupts.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
xen/arch/x86/hpet.c
xen/arch/x86/i8259.c
xen/arch/x86/io_apic.c
xen/arch/x86/irq.c
xen/drivers/passthrough/amd/iommu_init.c
xen/drivers/passthrough/vtd/iommu.c
xen/include/xen/irq.h